package org.tokaf;

import java.lang.reflect.InvocationTargetException;
import java.net.URI;
import java.util.ArrayList;
import java.util.Vector;

import javax.swing.JFrame;
import javax.xml.xpath.XPathExpressionException;

import org.tokaf.datasearcher.DataModifier;
import org.tokaf.datasearcher.DataSearcher;
import org.tokaf.datasearcher.SesameRepositorySearcher;
import org.tokaf.normalizer.LevelNormalizer;
import org.tokaf.normalizer.Normalizer;
import org.tokaf.normalizer.SimpleNormalizer;
import org.tokaf.normalizer.ordering.AscendingOrdering;
import org.tokaf.normalizer.ordering.DescendingOrdering;
import org.tokaf.normalizer.ordering.Ordering;

/**
 * <p> UserNormalizers gets from database the type and settings of Normalizer,
 * which has a user associated.</p> <p>Copyright (c) 2006</p>
 * @author Alan Eckhardt
 * @version 1.0
 */
public class UserNormalizers {

	ArrayList al = new ArrayList();

	String namespace = "http://www.muaddib.wz.cz/org.tokafOntology#";

	QueryFinder queryFinder;

	DataSearcher master;

	DataModifier masterModifier;

	String typeName = "http://www.w3.org/1999/02/22-rdf-syntax-ns#type";

	public static void main(String[] args) throws IllegalArgumentException,
			ClassNotFoundException, InstantiationException,
			IllegalAccessException, InvocationTargetException,
			XPathExpressionException {
		JFrame.setDefaultLookAndFeelDecorated(false);
		SesameRepositorySearcher tmp = new SesameRepositorySearcher();
		tmp.initSource("kim");
		UserNormalizers a = new UserNormalizers(
				"http://www.muaddib.wz.cz/org.tokafOntology#",
				new QueryFinder(
						"E:\\MojeProgramy\\eclipseProjects\\topkAlg\\queries.xml ",
						"Sesame"), tmp);

		// Normalizer[] norm=a.getUserNormalizers( "Alan" , new
		// String[]{"http://www.muaddib.wz.cz/comfortOfMakingFire",
		// "http://www.muaddib.wz.cz/comfortOfSleeping",
		// "http://www.muaddib.wz.cz/levelOfDanger",
		// "http://www.muaddib.wz.cz/levelOfProtection" });
		Normalizer[] norm = new Normalizer[10];
		SimpleNormalizer sm = new SimpleNormalizer();
		for (int i = 0; i < norm.length; i++)
			norm[i] = sm;
		/*
		 * a.addUserNormalizers(norm, "Alan", new String[]
		 * {"http://www.muaddib.wz.cz/comfortOfMakingFire",
		 * "http://www.muaddib.wz.cz/comfortOfSleeping",
		 * "http://www.muaddib.wz.cz/levelOfDanger",
		 * "http://www.muaddib.wz.cz/levelOfProtection" });
		 * a.addUserNormalizers(norm, "Betty", new String[]
		 * {"http://www.muaddib.wz.cz/comfortOfMakingFire",
		 * "http://www.muaddib.wz.cz/comfortOfSleeping",
		 * "http://www.muaddib.wz.cz/levelOfDanger",
		 * "http://www.muaddib.wz.cz/levelOfProtection" });
		 * a.addUserNormalizers(norm, "Ondra", new String[]
		 * {"http://www.muaddib.wz.cz/comfortOfMakingFire",
		 * "http://www.muaddib.wz.cz/comfortOfSleeping",
		 * "http://www.muaddib.wz.cz/levelOfDanger",
		 * "http://www.muaddib.wz.cz/levelOfProtection" });
		 * a.addUserNormalizers(norm, "Turbo", new String[]
		 * {"http://www.muaddib.wz.cz/comfortOfMakingFire",
		 * "http://www.muaddib.wz.cz/comfortOfSleeping",
		 * "http://www.muaddib.wz.cz/levelOfDanger",
		 * "http://www.muaddib.wz.cz/levelOfProtection" });
		 * a.addUserNormalizers(norm, "Jednicka", new String[]
		 * {"http://www.muaddib.wz.cz/comfortOfMakingFire",
		 * "http://www.muaddib.wz.cz/comfortOfSleeping",
		 * "http://www.muaddib.wz.cz/levelOfDanger",
		 * "http://www.muaddib.wz.cz/levelOfProtection" });
		 * a.addUserNormalizers(norm, "Ala", new String[]
		 * {"http://www.muaddib.wz.cz/comfortOfMakingFire",
		 * "http://www.muaddib.wz.cz/comfortOfSleeping",
		 * "http://www.muaddib.wz.cz/levelOfDanger",
		 * "http://www.muaddib.wz.cz/levelOfProtection" });
		 */
		a.deleteUserNormalizers("Alan", new String[] {
				"http://www.muaddib.wz.cz/hasTerrain",
				"http://www.muaddib.wz.cz/hasStartingCity",
				"http://www.muaddib.wz.cz/wasTrippedBy" });
		a.addUserNormalizers(norm, "Alan", new String[] {
				"http://www.muaddib.wz.cz/hasTerrain",
				"http://www.muaddib.wz.cz/hasStartingCity",
				"http://www.muaddib.wz.cz/wasTrippedBy" });

	}

	public UserNormalizers(QueryFinder queryFinder, DataSearcher master) {
		this.queryFinder = queryFinder;
		this.master = master;
		if (master instanceof DataModifier) {
			this.masterModifier = (DataModifier) master;
		} else
			this.masterModifier = null;
	}

	public UserNormalizers(String namespace, QueryFinder queryFinder,
			DataSearcher master) {
		this.namespace = namespace;
		this.queryFinder = queryFinder;
		this.master = master;
		if (master instanceof DataModifier) {
			this.masterModifier = (DataModifier) master;
		} else
			this.masterModifier = null;
	}

	public UserNormalizers(String namespace, QueryFinder queryFinder,
			DataSearcher master, DataModifier masterModifier) {
		this.namespace = namespace;
		this.queryFinder = queryFinder;
		this.master = master;
		this.masterModifier = masterModifier;
		// init();
	}

	protected String checkURI(String string) {
		URI a = java.net.URI.create(string);
		if (a.getAuthority() == null)
			return namespace + string;
		else
			return string;
	}

	protected String getUserNormalizerName(String user, String predicate) {
		ArrayList<String> params = new ArrayList<String>();
		params.add(checkURI(predicate));
		params.add(checkURI(user));
		String normQuery = queryFinder.getQuery("GetListOfNormalizers", 1,
				params);
		SesameRepositorySearcher normData = new SesameRepositorySearcher();
		normData.initSource(master);
		normData.initSearch(normQuery);
		if (normData.hasNext()) {
			return normData.getField(0).toString();
		} else
			return null;
	}

	/**
	 * <p> getUserNormalizer </p> Searches the database for a Normalizer, which
	 * user user associated with predicate predicate.
	 * @param user String
	 * @param predicate String
	 * @return Normalizer
	 */
	public Normalizer getUserNormalizer(String user, String predicate) {

		String normalizerName = getUserNormalizerName(user, predicate);
		if (normalizerName == null) {
			String predicateName = null;
			try {
				java.net.URI u = java.net.URI.create(predicate);
				predicateName = u.getSchemeSpecificPart();
			} catch (java.lang.IllegalArgumentException ex) {
				predicateName = predicate.toString();
			}
			normalizerName = namespace + predicateName + user + "sNormalizer";
		}
		ArrayList<String> params = new ArrayList<String>();
		params.add(normalizerName);
		String normQuery = queryFinder.getQuery("GetListOfNormalizers", 2,
				params);
		SesameRepositorySearcher normData = new SesameRepositorySearcher();
		normData.initSource(master);
		normData.initSearch(normQuery);

		Normalizer norm = getNormalizer(normData);
		if (norm != null) {
			norm.setUserName(user);
		}
		return norm;
	}

	/**
	 * <p> getUserNormalizer </p> Datasearcher normSearcher contains the
	 * definition of some Normalizer. This method create a new instance of
	 * Normalizer according to various settings possibly stored in database.
	 * @param normSearcher DataSearcher
	 * @return Normalizer
	 */
	protected Normalizer getNormalizer(DataSearcher normSearcher) {
		String normType = null;
		Vector<String> levelsVector = new Vector<String>();
		String orderingType = null;
		String innerNormalizerName = null;
		while (normSearcher.hasNext()) {
			String temp = normSearcher.getField(1).toString();
			if (temp.equals("http://www.w3.org/1999/02/22-rdf-syntax-ns#type")) {
				if (normSearcher.getField(2).toString().equals(
						namespace + "SimpleNormalizer"))
					normType = normSearcher.getField(2).toString();
				else if (normSearcher.getField(2).toString().equals(
						namespace + "LevelNormalizer"))
					normType = normSearcher.getField(2).toString();

			} else if (temp.equals(namespace + "hasOrdering")) {
				orderingType = normSearcher.getField(2).toString();
			} else if (temp.equals(namespace + "hasLevels")) {
				levelsVector.add(normSearcher.getField(2).toString());
			} else if (temp.equals(namespace + "hasInnerNormalizer")) {
				innerNormalizerName = normSearcher.getField(2).toString();
			}
			normSearcher.advance();
		}
		Normalizer norm = null;
		if (normType == null)
			return null;
		if (normType.equals(namespace + "SimpleNormalizer")) {
			Ordering ordering = null;
			if (orderingType.equals(namespace + "AscendingOrdering"))
				ordering = new AscendingOrdering();
			else if (orderingType.equals(namespace + "DescendingOrdering"))
				ordering = new DescendingOrdering();
			norm = new SimpleNormalizer(ordering);
		} else if (normType.equals(namespace + "LevelNormalizer")) {

			if (innerNormalizerName == null || innerNormalizerName.equals(""))
				return null;
			ArrayList<String> params = new ArrayList<String>();
			params.add(innerNormalizerName);
			String normQuery = queryFinder.getQuery("GetListOfNormalizers", 2,
					params);

			SesameRepositorySearcher normData = new SesameRepositorySearcher();
			normData.initSource(master);
			normData.initSearch(normQuery);
			Normalizer innerNormalizer = getNormalizer(normData);
			double[] levels = new double[levelsVector.size()];
			for (int j = 0; j < levels.length; j++) {
				levels[j] = Double.parseDouble(levelsVector.get(j).toString());
			}
			norm = new LevelNormalizer(innerNormalizer, levels);
		}
		return norm;
	}

	public Normalizer[] getUserNormalizers(String user, String predicates[]) {
		ArrayList<Normalizer> usersNormalizers = new ArrayList<Normalizer>();
		for (int i = 0; i < predicates.length; i++) {
			Normalizer norm = getUserNormalizer(user, predicates[i]);
			if (norm != null)
				usersNormalizers.add(norm);
		}
		Normalizer[] normalizers = new Normalizer[usersNormalizers.size()];
		for (int j = 0; j < normalizers.length; j++) {
			normalizers[j] = usersNormalizers.get(j);
		}
		return normalizers;
	}

	public Normalizer[] getUserNormalizers(String users[], String predicate) {
		ArrayList<Normalizer> usersNormalizers = new ArrayList<Normalizer>();
		for (int i = 0; i < users.length; i++) {
			Normalizer norm = getUserNormalizer(users[i], predicate);
			usersNormalizers.add(norm);
		}
		Normalizer[] normalizers = new Normalizer[usersNormalizers.size()];
		for (int j = 0; j < normalizers.length; j++) {
			normalizers[j] = usersNormalizers.get(j);
		}
		return normalizers;
	}

	protected void modifySimpleNormalizer(SimpleNormalizer norm,
			String normalizerName, boolean add) {
		normalizerName = checkURI(normalizerName);
		if (add)
			masterModifier.addTriple(normalizerName, typeName, namespace
					+ "SimpleNormalizer");
		if (norm.getOrdering() instanceof AscendingOrdering) {
			if (add)
				masterModifier.addTriple(normalizerName, namespace
						+ "hasOrdering", namespace + "AscendingOrdering");
			else
				masterModifier.deleteTriple(normalizerName, namespace
						+ "hasOrdering", namespace + "AscendingOrdering");
		} else if (norm.getOrdering() instanceof DescendingOrdering) {
			if (add)
				masterModifier.addTriple(normalizerName, namespace
						+ "hasOrdering", namespace + "DescendingOrdering");
			else
				masterModifier.deleteTriple(normalizerName, namespace
						+ "hasOrdering", namespace + "DescendingOrdering");
		}
		if (!add)
			masterModifier.deleteTriple(normalizerName, typeName, namespace
					+ "SimpleNormalizer");
	}

	protected void modifyLevelNormalizer(LevelNormalizer norm,
			String normalizerName, boolean add) {
		masterModifier.addTriple(normalizerName, typeName, namespace
				+ "LevelNormalizer");
		if (norm.getInnerNormalizer() instanceof SimpleNormalizer) {
			modifySimpleNormalizer(
					(SimpleNormalizer) norm.getInnerNormalizer(),
					normalizerName + "sInnerNormalizer", add);
		} else if (norm.getInnerNormalizer() instanceof LevelNormalizer) {
			modifyLevelNormalizer((LevelNormalizer) norm.getInnerNormalizer(),
					normalizerName + "sInnerNormalizer", add);
		}

		if (add)
			masterModifier.addTriple(normalizerName, namespace
					+ "hasInnerNormalizer ", normalizerName
					+ "sInnerNormalizer");
		else
			masterModifier.deleteTriple(normalizerName, namespace
					+ "hasInnerNormalizer ", normalizerName
					+ "sInnerNormalizer");

		double[] levels = norm.getLevels();
		for (int i = 0; i < levels.length; i++) {
			if (add)
				masterModifier.addTriple(normalizerName, namespace
						+ "hasLevels", new Double(levels[i]),
						"http://www.w3.org/2001/10/XMLSchema#decimal");
			else
				masterModifier.deleteTriple(normalizerName, namespace
						+ "hasLevels", new Double(levels[i]),
						"http://www.w3.org/2001/10/XMLSchema#decimal");

		}
	}

	protected void modifyRelation(String normalizerName, String predicate,
			String user, boolean add) {
		predicate = checkURI(predicate);
		normalizerName = checkURI(normalizerName);

		if (add)
			masterModifier.addTriple(predicate, namespace + user
					+ "sNormalizer", normalizerName);
		else
			masterModifier.deleteTriple(predicate, namespace + user
					+ "sNormalizer", normalizerName);
	}

	protected void modifyNormalizer(Normalizer norm, String user,
			String predicate, boolean add) {
		if (masterModifier == null)
			return;
		String predicateName = null;

		try {
			java.net.URI u = java.net.URI.create(predicate);
			predicateName = u.getSchemeSpecificPart();
		} catch (java.lang.IllegalArgumentException ex) {
			predicateName = predicate.toString();
		}
		String normalizerName = getUserNormalizerName(user, predicate);
		if (normalizerName == null)
			normalizerName = namespace + predicateName + user + "sNormalizer";
		if (norm instanceof SimpleNormalizer) {
			modifySimpleNormalizer((SimpleNormalizer) norm, normalizerName, add);
		} else if (norm instanceof LevelNormalizer) {
			modifyLevelNormalizer((LevelNormalizer) norm, normalizerName, add);
		}
		modifyRelation(normalizerName, predicate, user, add);
	}

	public void deleteUserNormalizer(String user, String predicate) {
		if (masterModifier == null)
			return;
		String predicateName = null;

		predicateName = checkURI(predicate);
		Normalizer norm = getUserNormalizer(user, predicateName);
		modifyNormalizer(norm, user, predicate, false);
	}

	public void addUserNormalizer(Normalizer norm, String user, String predicate) {
		deleteUserNormalizer(user, predicate);
		modifyNormalizer(norm, user, predicate, true);
	}

	public void deleteUserNormalizers(String user, String predicate[]) {
		for (int i = 0; i < predicate.length; i++)
			deleteUserNormalizer(user, predicate[i]);
	}

	public void deleteUserNormalizers(String user[], String predicate) {
		for (int i = 0; i < user.length; i++)
			deleteUserNormalizer(user[i], predicate);
	}

	public void addUserNormalizers(Normalizer[] norm, String user,
			String predicate[]) {
		for (int i = 0; i < predicate.length; i++)
			addUserNormalizer(norm[i], user, predicate[i]);
	}

	public void addUserNormalizers(Normalizer[] norm, String user[],
			String predicate) {
		for (int i = 0; i < user.length; i++)
			addUserNormalizer(norm[i], user[i], predicate);
	}
	/*
	 * protected double[] getLevels(Node levelsNode) { Vector levelsVector = new
	 * Vector(); NodeList levelNodes = levelsNode.getChildNodes(); for (int j =
	 * 1; j < levelNodes.getLength(); j++) { Node level = levelNodes.item(j); if
	 * (level == null || level.getTextContent().equals("")) break; try {
	 * Double.parseDouble((String) level.getTextContent());
	 * levelsVector.add(level.getTextContent()); } catch (Exception ex) { } }
	 * double[] levels = new double[levelsVector.size()]; for (int k = 0; k <
	 * levels.length; k++) { levels[k] = Double.parseDouble((String)
	 * levelsVector.get(k)); } return levels; }
	 */
	/*
	 * private void parsePredicate(Node page) { NamedNodeMap names =
	 * page.getAttributes(); Node name = names.getNamedItem("name"); String
	 * namee = name.getNodeValue(); NormalizerContainer cont = new
	 * NormalizerContainer(); al.add(cont); cont.predicate = namee; NodeList tmp =
	 * page.getChildNodes(); Normalizer norm = null; String normalizerName =
	 * null; String user = null; String order = null; double[] levels = null;
	 * for (int i = 0; i < tmp.getLength(); i++) { Node pagesNode = tmp.item(i);
	 * if (pagesNode.getNodeName().equals("Normalizer")) { normalizerName =
	 * pagesNode.getTextContent(); } else if
	 * (pagesNode.getNodeName().equals("User")) { NamedNodeMap userAttributes =
	 * pagesNode.getAttributes(); Node nameUser =
	 * userAttributes.getNamedItem("name"); user = nameUser.getNodeValue();
	 * NodeList tmpUser = pagesNode.getChildNodes(); for (i = 0; i <
	 * tmpUser.getLength(); i++) { Node userNode = tmpUser.item(i); if
	 * (userNode.getNodeName().equals("Order")) { order =
	 * userNode.getTextContent(); } else if
	 * (userNode.getNodeName().equals("Levels")) { levels = getLevels(userNode); } } } }
	 * Ordering ordering = null; if (order.equals("Ascending")) ordering = new
	 * AscendingOrdering(); else if (order.equals("Descending")) ordering = new
	 * DescendingOrdering(); if (normalizerName.equals("LevelNormalizer")) {
	 * SimpleNormalizer temp = new SimpleNormalizer(ordering, user); norm = new
	 * LevelNormalizer(temp, levels, user); } else { norm = new
	 * SimpleNormalizer(ordering, user); } if (norm != null)
	 * cont.norm.add(norm); }
	 */
	/*
	 * private void init() { try { DocumentBuilderFactory docBuilderFactory =
	 * DocumentBuilderFactory.newInstance(); DocumentBuilder docBuilder =
	 * docBuilderFactory.newDocumentBuilder(); Document doc =
	 * docBuilder.parse(new File(path)); // normalize text representation
	 * doc.getDocumentElement().normalize(); NodeList listOfSettings =
	 * doc.getElementsByTagName("Ratings"); Node settingsNode =
	 * listOfSettings.item(0); NodeList tmp = settingsNode.getChildNodes(); int
	 * i = 0; for (i = 0; i < tmp.getLength(); i++) { Node pagesNode =
	 * tmp.item(i); if (pagesNode.getNodeName().equals("Predicates")) break; }
	 * NodeList pages = tmp.item(i).getChildNodes(); for (int j = 0; j <
	 * pages.getLength(); j++) { Node page = pages.item(j); if
	 * (page.getNodeName().equals("Predicate")) { parsePredicate(page); } } }
	 * catch (SAXParseException err) { System.out.println("** Parsing error" + ",
	 * line " + err.getLineNumber() + ", uri " + err.getSystemId());
	 * System.out.println(" " + err.getMessage()); } catch (SAXException e) {
	 * Exception x = e.getException(); ((x == null) ? e : x).printStackTrace(); }
	 * catch (Throwable t) { t.printStackTrace(); } } public Normalizer[]
	 * getUserNormalizers(String users[], String predicate) { for (int i = 0; i <
	 * al.size(); i++) { NormalizerContainer cont = (NormalizerContainer)
	 * al.get(i); if (cont.predicate.equals(predicate)) { Normalizer norm[];
	 * ArrayList usersNormalizers = new ArrayList(); for (int j = 0; j <
	 * cont.norm.size(); j++) { Normalizer userNorm = (Normalizer)
	 * cont.norm.get(j); for (int k = 0; k < users.length; k++) { if
	 * (userNorm.getUserName().equals(users[k])) usersNormalizers.add(userNorm); } }
	 * norm = new Normalizer[usersNormalizers.size()]; for (int j = 0; j <
	 * norm.length; j++) { norm[j] = (Normalizer) usersNormalizers.get(j); }
	 * return norm; } } return null; } public Normalizer[]
	 * getUserNormalizers(String user, String predicates[]) { Normalizer norm[] =
	 * null; ArrayList usersNormalizers = new ArrayList(); for (int i = 0; i <
	 * al.size(); i++) { NormalizerContainer cont = (NormalizerContainer)
	 * al.get(i); for (int k = 0; k < predicates.length; k++) { if
	 * (cont.predicate.equals(predicates[k])) { for (int j = 0; j <
	 * cont.norm.size(); j++) { Normalizer userNorm = (Normalizer)
	 * cont.norm.get(j); if (userNorm.getUserName().equals(user))
	 * usersNormalizers.add(userNorm); } } } } norm = new
	 * Normalizer[usersNormalizers.size()]; for (int j = 0; j < norm.length;
	 * j++) { norm[j] = (Normalizer) usersNormalizers.get(j); } return norm; }
	 * protected void lockFile() { } protected void
	 * updatePreferences(Normalizer[] norm, String predicate) { for (int i = 0;
	 * i < al.size(); i++) { NormalizerContainer cont = (NormalizerContainer)
	 * al.get(i); if (cont.predicate.equals(predicate)) { for (int j = 0; j <
	 * norm.length; j++) { for (int l = 0; l < cont.norm.size(); l++) { if
	 * (((Normalizer) cont.norm.get(l)).getUserName().equals(norm[j])) {
	 * cont.norm.remove(l); if (norm[j] != null) cont.norm.add(norm[j]); } } }
	 * break; } } } public void updatePreferences(Normalizer[][] norm, String[]
	 * predicates) { for (int k = 0; k < predicates.length; k++)
	 * updatePreferences(norm[k], predicates[k]); } public void write() { }
	 * public void writePreferences(Normalizer[][] norm, String[] predicates) {
	 * lockFile(); init(); updatePreferences(norm, predicates); write(); }
	 */
}

class NormalizerContainer {
	ArrayList norm = new ArrayList();

	String predicate;
}
